package myList_1009.linked_list_1011;

public class OperateLinkedList {
    // 方法的返回值类型选择 Node，原因是尾插也会修改头结点（当原来的链表是空的链表时）
    private static Node 尾插元素(Node head, int e) {
        // 1) 把元素放入结点中
        Node node = new Node(e);

        // 2) 分情况处理
        // 2.1) 目前链表是一个空的链表 <=> 没有头结点 <=> head == null
        if (head == null) {
            node.next = null;   // 这句话可以省略
            return node;
        }
        // 2.2) 链表中至少有一个结点时
        Node last = head;
        while (last.next != null) {
            last = last.next;
        }
        // 此处，last.next == null <=> last 就是原链表的最后一个结点
        node.next = null;       // 这句话可以省略
        last.next = node;

        return head;
    }

    private static Node 尾插结点(Node head, Node node) {
        if (head == null) {
            node.next = null;   // 这句话可以省略
            return node;
        }
        Node last = head;
        while (last.next != null) {
            last = last.next;
        }
        // 此处，last.next == null <=> last 就是原链表的最后一个结点
        node.next = null;       // 这句话可以省略
        last.next = node;

        return head;
    }

    private static Node 尾删(Node head) {
        if (head == null) {
            // 让我们尾删的链表是一个空链表（通过抛出异常进行抱怨）
            throw new RuntimeException();
        }

        if (head.next == null) {
            // 没有第二个结点，说明只有一个结点
            return null;
        }

        // 找到倒数第二个结点
        Node lastOfLast = head;
        while (lastOfLast.next.next != null) {
            lastOfLast = lastOfLast.next;
        }
        // lastOfLast.next.next 一定是 null
        // 说明 lastOfLast.next 一定是最后一个结点
        // lastOfLast 就是倒数第二个结点
        lastOfLast.next = null;

        return head;
    }

    // 不需要传入头结点，因为整个过程和头结点无关
    // 指定结点不是头结点也不是尾结点
    private static void 将e插入到到指定结点之后(Node node, int e) {
        Node newNode = new Node(e);

        newNode.next = node.next;
        node.next = newNode;
    }


    // 不需要传入头结点，因为整个过程和头结点无关
    // 指定结点不是头结点也不是尾结点
    private static void 插入指定结点后的结点(Node node) {
        // 先找到的 node 的下个结点，记为 nextOfNode
        Node nextOfNode = node.next;
        // 再找到 node 的下一个的下一个结点，记为 nextOfNext
        Node nextOfNext = nextOfNode.next;
        // 让 node 的 next 指向 下下个结点
        node.next = nextOfNext;

        // node.next = node.next.next;  // 这句话可以完成
    }

    public static void main(String[] args) {
        Node head = null;
        head = 尾插元素(head, 100);
        head = 尾插元素(head, 200);
        head = 尾插元素(head, 300);
        head = 尾插元素(head, 400);

        head = 尾删(head);
        head = 尾删(head);
        head = 尾删(head);
        head = 尾删(head);
    }
}
